#include "StdAfx.h"
#include "MainState.h"

#include "QuadTreeDemoState.h"
#include "GrassLoaderDemoState.h"
#include "ForestLoaderDemoState.h"
#include "ImpostorDemoState.h"


MainState::MainState()
	: FEApplication(), FEngine::KeyboardInputListener(), FEngine::MouseInputListener()
{
	mMap				= NULL;
	mCameraHandler		= NULL;

	mStatPanel			= NULL;
	
	soleil				= NULL;
	terre				= NULL;
	lune				= NULL;
	soleilNode_base		= NULL;
	terreNode_base		= NULL;
	terreNode_center	= NULL;
	luneNode_base		= NULL;
}

MainState::~MainState()
{
	FEngine::InputManager::getInstance()->unregisterKeyboardInputListener(this);
	FEngine::InputManager::getInstance()->unregisterMouseInputListener(this);
	
	delete mMap;
	delete mCameraHandler;

	delete mStatPanel;
	
	delete soleil;
	delete terre;
	delete lune;
	delete soleilNode_base;
	delete terreNode_base;
	delete terreNode_center;
	delete luneNode_base;

	for (std::list<FEngine::TextLabel*>::iterator it = mListLabels.begin(); it != mListLabels.end(); ++it)
		delete *it;
}

void MainState::initialize()
{
	FEngine::FEApplication::initialize();
	FEngine::InputManager::getInstance()->registerKeyboardInputListener(this);
	FEngine::InputManager::getInstance()->registerMouseInputListener(this);
	
	FEngine::CoreEngine::getInstance()->setFogColor(200, 240, 200);
	FEngine::CoreEngine::getInstance()->setFogStartDistance(25.0f);
	FEngine::CoreEngine::getInstance()->setFogEndDistance(300.0f);
	FEngine::CoreEngine::getInstance()->enableFog();
	
	//mMap = new FEngine::HeightMap(512, 512, 40, "terrainheight.raw");
	//addChild(mMap);

	mCameraHandler = new FEngine::FreeCameraHandler(FEngine::CoreEngine::getInstance()->getCamera(), Vector3(0, 50, 0), Vector3(1, 0, 1));
	addChild(mCameraHandler);
	
	FEngine::CoreEngine::getInstance()->setSkyDome("skydome1.dds", 1.0f);

	mStatPanel = new StatPanel();
	addGUIElement(mStatPanel);

	// Create our solar system
	soleilNode_base = new FEngine::Node();
	soleilNode_base->setPosition(Vector3(256.0f, 150.0f, 256.0f));
	soleilNode_base->setScale(Vector3(10.0f, 10.0f, 10.0f));
	addChild(soleilNode_base);
	
	FEngine::Node* node = new FEngine::Node();
	soleilNode_base->addChild(node);
	node->setRotation(Vector3(10.0f, 0.0f, 0.0f));

	soleil = new FEngine::PrimitiveCube(3.0f);
	node->addChild(soleil);
	soleil->setColor(255, 255, 0);
	
	terreNode_base = new FEngine::Node();
	soleilNode_base->addChild(terreNode_base);
	
	terreNode_center = new FEngine::Node();
	terreNode_base->addChild(terreNode_center);
	terreNode_center->setPosition(Vector3(8.0f, 0.0f, 0.0f));
	terreNode_center->setRotation(Vector3(0.0f, 7.0f, 0.0f));

	terre = new FEngine::PrimitiveCube(2.0f);
	terreNode_center->addChild(terre);
	terre->setScale(Vector3(0.2f, 0.2f, 0.2f));
	terre->setColor(0, 0, 255);
	
	luneNode_base = new FEngine::Node();
	addChild(luneNode_base);
	lune = new FEngine::PrimitiveCube();
	luneNode_base->addChild(lune);
	lune->setPosition(Vector3(0.0f, 12.0f, 0.0f));
	lune->setScale(Vector3(0.8f, 0.8f, 0.8f));
	lune->setColor(255, 255, 255);

	// Create our GUI texts
	mListLabels.push_back(new FEngine::TextLabel("Welcome in the DirectX project of Fournier - Hamon - Houari", 350, 10, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("Camera controls : ", 1200, 600, 0, 0, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("ZQSD (+maj) : move (+speed)", 1250, 640, 0, 0, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("AE : move up and down", 1250, 680, 0, 0, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("Mouse button 1 + movement : rotation", 1250, 720, 0, 0, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());

	mListLabels.push_back(new FEngine::TextLabel("Escape to quit or return to this menu", 1270, 10, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());

	mListLabels.push_back(new FEngine::TextLabel("This project is about handling a lot of object in the scene", 100, 200, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("The following demos show the techniques used :", 120, 240, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("(Press the given number key to access the demo)", 120, 280, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	
	mListLabels.push_back(new FEngine::TextLabel("1 - Quad Tree : show how the quad tree nodes are created", 140, 340, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("2 - Grass loader : show the loading of 2D objects and compare the performance against a standard loading", 140, 380, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("3 - Forest loader : show the loading of 3D objects and compare the performance against a standard loading (long loading)", 140, 420, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("4 - Impostor : show how the impostor for 3D object works", 140, 460, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());
	mListLabels.push_back(new FEngine::TextLabel("5 - Infinite forest : show the final result in an awesome (almost) infinite forest !", 140, 500, 0, 200, 22, FEngine::ColorRGB(255, 255, 255)));
	addGUIElement(mListLabels.back());

}

void MainState::update(double _elapsedTime)
{
	FEApplication::update(_elapsedTime);

	// Update out solar system
	float sp = (float)(_elapsedTime / 1000.0);
	soleil->rotate(0, 0, D3DXToRadian(-45.0f * sp));
	terreNode_base->rotate(0, 0, D3DXToRadian(-90.0f * sp));
	terre->rotate(0, 0, D3DXToRadian(-60.0f * sp));
	luneNode_base->setPosition(terre->getPositionWorld());
	luneNode_base->rotate(0, D3DXToRadian(-160.0f * sp), 0);
	lune->rotate(D3DXToRadian(-60.0f * sp), 0, 0);
}

void MainState::updateGUI(double _elapsedTime)
{
	FEApplication::updateGUI(_elapsedTime);
}


void MainState::render(double _elapsedTime)
{
	FEApplication::render(_elapsedTime);
}

void MainState::keyPressed(int _key)
{
	switch (_key)
	{
		case FEngine::InputManager::KEY_ESCAPE:
			FEngine::CoreEngine::getInstance()->stop();
			break;
	
		case FEngine::InputManager::KEY_1:
			FEngine::CoreEngine::getInstance()->setApplication(new QuadTreeDemoState());
			break;
	
		case FEngine::InputManager::KEY_2:
			FEngine::CoreEngine::getInstance()->setApplication(new GrassLoaderDemoState());
			break;
	
		case FEngine::InputManager::KEY_3:
			FEngine::CoreEngine::getInstance()->setApplication(new ForestLoaderDemoState());
			break;
	
		case FEngine::InputManager::KEY_4:
			FEngine::CoreEngine::getInstance()->setApplication(new ImpostorDemoState());
			break;
	}
}

void MainState::keyReleased(int _key)
{
}

void MainState::mouseButtonPressed(int _button, const Vector2& _position)
{
}

void MainState::mouseButtonReleased(int _button, const Vector2& _position)
{
}

void MainState::mouseMoved(const Vector2& _delta)
{
}
